Ansible Galaxyを使ってMacを構築してみた -2022-
こんにちは。たかやまです。
今まで生粋のWindowsユーザでしたが、この度Macが支給(※Windows/Mac選べます)されたのでこれからのMac利用を見据えてAnsibleでMacを構築してみたいと思います。
今回はAnsible GalaxyでMac構築に良さげなRoleがあったので記事にしたいと思います。
Ansible Galaxyとは
Ansibleで利用できるRoleやCollections (module, plugin, roleをまとめた単位)を配布するコミュニティサイトです。
今回はこのAnsible Galaxyで配布されているgeerlingguy.macを使用してMacを構築してみます。
構成
- macOS 12.3.1 M1/16GB
- Homebrew 3.4.4
- Ansible-core 2.12.4/Ansible 5
Mac構築手順
Homebrewインストール
Ansibleはpipでインストールするのが公式推奨手順ですが、個別にpipをインストールしたりpath通したりするのが手間なため今回はHomebrewでインストールします。
そのため、まずはHomebrewをインストールします。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
インストール後、homebrewのpathを通す。 ※zshの場合
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/your_username/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"
インストールできました。
% brew --version Homebrew 3.4.5 Homebrew/homebrew-core (git revision 492433b71e4; last commit 2022-04-07)
Ansibleインストール
homebrewでansibleをインストールします。
brew install ansible
Ansibleもサクッとインストールできます。
% ansible --version ansible [core 2.12.4] config file = None configured module search path = ['/Users/your_username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /opt/homebrew/Cellar/ansible/5.5.0/libexec/lib/python3.10/site-packages/ansible ansible collection location = /Users/your_username/.ansible/collections:/usr/share/ansible/collections executable location = /opt/homebrew/bin/ansible python version = 3.10.2 (main, Feb 2 2022, 05:51:25) [Clang 13.0.0 (clang-1300.0.29.3)] jinja version = 3.1.1 libyaml = True
Ansible Galaxyインストール
Ansible-Galaxyからgeerlingguy.macをインストールします。
ansible-galaxy collection install geerlingguy.mac
Ansible-Galaxyのパッケージはカレントディレクトリ配下の.ansible
にダウンロードされます。あとは後述のPlaybookの中でインストールしたRole指定することで利用可能となります。
% ansible-galaxy collection list . . # /Users/your_username/.ansible/collections/ansible_collections Collection Version ----------------- ------- community.general 4.7.0 geerlingguy.mac 1.4.0
Playbookの作成
先ほどインストールしたgeerlingguy.mac
は3つのRoleで構成されています。
作成するPlaybookには利用するRoleで参照される変数を定義していく形になります。
Role | 機能 |
---|---|
geerlingguy.mac.homebrew | homebrewを使ったソフトウェア管理をする |
geerlingguy.mac.mas | Mac App Storeのソフトウェアを管理する |
geerlingguy.mac.dock | dockのレイアウト管理をする |
Playbook(site.yml)の記述例は以下の通りです。
今回インストールしたRoleだけでセットアップする場合は、こちらのPlaybookだけ用意すれば大丈夫です。
- hosts: localhost connection: local become_user: your_computename gather_facts: false vars: ansible_machine: arm64 # arm64/x86_64を指定する。今回はM1 Macなのでarm64を指定 ansible_user_id: your_username # 実行ユーザID ansible_user_gid: your_groupid # 実行ユーザのグループID homebrew_cask_apps: # インストールしたいcaskアプリをリスト形式で指定 - 1password homebrew_cask_uninstalled_apps: # アンインストールしたいcaskアプリをリスト形式で指定 - alfred homebrew_installed_packages: # インストールしたいGUIアプリをリスト形式で指定 - awscli homebrew_uninstalled_packages: # アンインストールしたいGUIアプリをリスト形式で指定 - autoconf mas_installed_apps: # インストールしたいMac Apple Storeアプリをリスト形式で指定 - { id: 409183694, name: "Keynote" } mas_uninstalled_apps: # アンインストールしたいMac Apple Storeアプリをリスト形式で指定 - { id: 682658836, name: "GarageBand" } dockitems_persist: # Dockの配列を指定 - name: Launchpad path: "/Applications/Launchpad.app/" pos: 1 roles: # インストールしたRoleを指定 - role: geerlingguy.mac.homebrew tags: homebrew - role: geerlingguy.mac.mas tags: mas - role: geerlingguy.mac.dock tags: dock
ここに定義した変数以外にBrewfileを使ったインストール方法など他にも変数が用意されているので、気になった方はドキュメントをご確認ください。
Playbookの実行
以下のコマンドを実行することで、先ほど定義したPlaybook(site.yml)を元にRoleを読み込んでMacのセットアップをしてくれます。
ansible-playbook -i localhost, -c local site.yml
実行例(クリックで展開)
% ansible-playbook -i localhost, -c local site.yml PLAY [localhost] *********************************************************************************************************************************************** TASK [geerlingguy.mac.homebrew : Determine Homebrew ownership variables] *************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure Homebrew parent directory has correct permissions (M1).] *************************************************************** [WARNING]: Platform darwin on host localhost is using the discovered Python interpreter at /opt/homebrew/bin/python3.9, but future installation of another Python interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.12/reference_appendices/interpreter_discovery.html for more information. ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure Homebrew parent directory has correct permissions (MacOS >= 10.13).] *************************************************** skipping: [localhost] TASK [geerlingguy.mac.homebrew : Ensure Homebrew parent directory has correct permissions (MacOS < 10.13).] **************************************************** skipping: [localhost] TASK [geerlingguy.mac.homebrew : Ensure Homebrew directory exists.] ******************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure Homebrew is installed.] ************************************************************************************************ ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure proper permissions and ownership on homebrew_brew_bin_path dirs.] ****************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure proper ownership on homebrew_install_path subdirs.] ******************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Check if homebrew binary is already in place.] ******************************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Symlink brew to homebrew_brew_bin_path.] ************************************************************************************** skipping: [localhost] TASK [geerlingguy.mac.homebrew : Ensure proper homebrew folders are in place.] ********************************************************************************* ok: [localhost] => (item=Cellar) ok: [localhost] => (item=Homebrew) ok: [localhost] => (item=Frameworks) ok: [localhost] => (item=Caskroom) ok: [localhost] => (item=bin) ok: [localhost] => (item=etc) ok: [localhost] => (item=include) ok: [localhost] => (item=lib) ok: [localhost] => (item=opt) ok: [localhost] => (item=sbin) ok: [localhost] => (item=share) ok: [localhost] => (item=share/zsh) ok: [localhost] => (item=share/zsh/site-functions) ok: [localhost] => (item=var) TASK [geerlingguy.mac.homebrew : Force update brew after installation.] **************************************************************************************** skipping: [localhost] TASK [geerlingguy.mac.homebrew : Where is the cache?] ********************************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Ensure configured taps are tapped.] ******************************************************************************************* ok: [localhost] => (item=homebrew/core) TASK [geerlingguy.mac.homebrew : Ensure blacklisted cask applications are not installed.] ********************************************************************** ok: [localhost] => (item=alfred) TASK [geerlingguy.mac.homebrew : Install configured cask applications.] **************************************************************************************** ok: [localhost] => (item=1password) TASK [geerlingguy.mac.homebrew : Ensure blacklisted homebrew packages are not installed.] ********************************************************************** ok: [localhost] => (item=autoconf) TASK [geerlingguy.mac.homebrew : Ensure configured homebrew packages are installed.] *************************************************************************** ok: [localhost] => (item=awscli) TASK [geerlingguy.mac.homebrew : Upgrade all homebrew packages (if configured).] ******************************************************************************* skipping: [localhost] TASK [geerlingguy.mac.homebrew : Check for Brewfile.] ********************************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.homebrew : Install from Brewfile.] ******************************************************************************************************* skipping: [localhost] TASK [geerlingguy.mac.dock : Install dockutil.] **************************************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.dock : Remove configured Dock items.] **************************************************************************************************** TASK [geerlingguy.mac.dock : Ensure required dock items exist.] ************************************************************************************************ included: /Users/your_username/.ansible/collections/ansible_collections/geerlingguy/mac/roles/dock/tasks/dock-add.yml for localhost => (item={'name': 'Launchpad', 'path': '/Applications/Launchpad.app/', 'pos': 1}) TASK [geerlingguy.mac.dock : See if Dock item Launchpad exists.] *********************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.dock : Ensure Dock item Launchpad exists.] *********************************************************************************************** skipping: [localhost] TASK [geerlingguy.mac.dock : Ensure dock items are in correct position.] *************************************************************************************** included: /Users/your_username/.ansible/collections/ansible_collections/geerlingguy/mac/roles/dock/tasks/dock-position.yml for localhost => (item={'name': 'Launchpad', 'path': '/Applications/Launchpad.app/', 'pos': 1}) TASK [geerlingguy.mac.dock : Check the current Dock position of Launchpad.] ************************************************************************************ ok: [localhost] TASK [geerlingguy.mac.dock : Get current dock item position from output.] ************************************************************************************** ok: [localhost] TASK [geerlingguy.mac.dock : Move dock item to the correct position.] ****************************************************************************************** skipping: [localhost] PLAY RECAP ***************************************************************************************************************************************************** localhost : ok=21 changed=0 unreachable=0 failed=0 skipped=9 rescued=0 ignored=0
Tips
私が利用した時点で、以下のRoleの実行元コマンドでエラーがあったので共有です。
Role | 不具合 |
---|---|
geerlingguy.mac.mas | MasでのUninstallが動作しない ・mas-cli/mas#313 |
geerlingguy.mac.dock | homebrewでインストールしたdockutilが動作しないため、 別途最新のdockutilをインストールする ・kcrawford/dockutil#127 |
まとめ
今回geerlingguy.macを使用したMacのセットアップ方法をご紹介しました。こちらのRoleを利用することでAnsibleに詳しくなくても簡単にMac構築を自動化をできると思います。
また、こちらのRoleを使うだけでもだいぶ構築を自動化ができますが、Ansibleが提供している他のCollectionsを利用することでシステム設定ファイルなどの細かい管理もできますの興味の湧いた方はぜひAnsibleのドキュメントをのぞいてみてください。
参考までに、今回私が構築に利用したPlaybookをGitHubにあげておきます。
以上、たかやまでした!